<?php

namespace app\index\controller;

use think\facade\View;
use think\facade\Session;
use think\facade\Cache;
use think\facade\Cookie;
use think\facade\Db;
use think\helper\Str;
use app\common\QrcodeUtil;
use app\common\variable\MsgCode;
use think\exception\ValidateException;
use app\common\validate\Login as LoginValidate;
use app\common\model\User as UserModel;
use app\common\model\UserVip as UserVipModel;
use app\common\model\UserDevices as UserDevicesModel;
use app\common\model\UserInfo as UserInfoModel;
use app\common\model\UserTimer as UserTimerModel;
use app\common\model\UserLoginLog as UserLoginLogModel;
use app\common\model\UserWx as UserWxModel;
use app\common\model\UserQq as UserQqModel;
use app\common\model\PushTask as PushTaskModel;
use app\common\controller\Captcha as CaptchaController;
use sendSms\SendSms;
use app\common\UploadFile;
use think\Exception;


class Login extends Base
{
    public function index()
    {
        if (request()->isAjax()) {
            $D = request()->post();
            $is_imgcode = intval(Cookie::get('is_imgcode'), 0);
            if ($is_imgcode && $is_imgcode >= config('captcha.error_sum')) {
                if (!CaptchaController::captcha_check($D))
                    return $this->ajaxReturn('验证码错误', MsgCode::$captcha);
            }
            $errorCode = MsgCode::$error;
            $is_imgcode = $is_imgcode + 1;
            if ($is_imgcode && $is_imgcode >= config('captcha.error_sum')) $errorCode = MsgCode::$captcha;
            /**
             * 用户验证
             */
            try {
                validate(LoginValidate::class)->scene('login')->check($D);
            } catch (ValidateException $e) {
                Cookie::set('is_imgcode', $is_imgcode);
                return $this->ajaxReturn($e->getError(), $errorCode);
            }
            $where[$D['is_username_type']] = $D['username'];
            $UserPassword = UserModel::getUserPassword($where);
            /*验证密码*/
            if (!$UserPassword) {
                Cookie::set('is_imgcode', $is_imgcode);
                return $this->ajaxReturn('用户不存在', $errorCode);
            }
            if (UserModel::getPassword($UserPassword['password_hash'], $D['password']) != $UserPassword['password']) {
                Cookie::set('is_imgcode', $is_imgcode);
                return $this->ajaxReturn('密码不正确', $errorCode);
            }
            /*验证用户状态*/
            $UserInfo = UserModel::getWebUserInfo(['user.id' => $UserPassword['id']]);
            if (!$UserInfo) {
                Cookie::set('is_imgcode', $is_imgcode);
                return $this->ajaxReturn('用户信息不存在', $errorCode);
            }
            if (!$UserInfo['status']) {
                Cookie::set('is_imgcode', $is_imgcode);
                return $this->ajaxReturn($UserInfo['disable_msg'], $errorCode);
            }
            $UserTimer = UserTimerModel::where(['uid' => $UserInfo['id']])->find();
            $UserTimer->login_time = time();
            $UserTimer->login_ip = request()->ip();
            $UserTimer->login_devices = substr(request()->header('user-agent'), 0, 200);
            $UserLoginLog = new UserLoginLogModel;
            $UserLoginLog->uid = $UserInfo->id;
            $UserLoginLog->appid = request()->ApiInfo['app_id'];
            $UserLoginLog->ip = request()->ip();
            $UserLoginLog->devices_id = substr(request()->header('user-agent'), 0, 200);
            if (!empty($D['cache']) && $D['cache'])
                $this->cacheUserInfo($UserInfo);
            Db::startTrans();
            try {
                $UserTimer->save();
                $UserLoginLog->save();
                Db::commit();
                $this->setSuccessLogin($UserInfo);
                Cookie::delete('is_imgcode');
                return $this->ajaxReturn('登录成功', MsgCode::$success, $UserInfo);
            } catch (Exception $e) {
                Db::rollback();
                return $this->ajaxReturn('登录失败，请重试', $errorCode);
            }
        } else {
            return View::fetch();
        }
    }
    public function vcode()
    {
        if (request()->isAjax()) {
            $D = request()->post();
            /**
             * 用户验证
             */
            try {
                validate(LoginValidate::class)->scene('vcode')->check($D);
            } catch (ValidateException $e) {
                return $this->ajaxReturn($e->getError(), MsgCode::$error);
            }
            $SendSms = new SendSms;
            $SendSms->sendType = $D['is_username_type'];
            $SendSms->username = $D['username'];
            $SendSms->vcode = $D['vcode'];
            $SendSms->action = $D['type'];
            if (!$SendSms->verification()) {
                return $this->ajaxReturn($SendSms->getError(), MsgCode::$error);
            }

            $where['user.' . $D['is_username_type']] = $D['username'];
            /*验证用户状态*/
            $UserInfo = UserModel::getWebUserInfo($where);
            if (!$UserInfo) {
                return $this->ajaxReturn('用户信息不存在', MsgCode::$error);
            }
            if (!$UserInfo['status']) {
                return $this->ajaxReturn($UserInfo['disable_msg'], MsgCode::$error);
            }
            $UserTimer = UserTimerModel::where(['uid' => $UserInfo['id']])->find();
            $UserTimer->login_time = time();
            $UserTimer->login_ip = request()->ip();
            $UserTimer->login_devices = request()->header('user-agent');
            $UserLoginLog = new UserLoginLogModel;
            $UserLoginLog->uid = $UserInfo->id;
            $UserLoginLog->appid = request()->ApiInfo['app_id'];
            $UserLoginLog->ip = request()->ip();
            $UserLoginLog->devices_id = substr(request()->header('user-agent'), 0, 200);
            if (!empty($D['cache']) && $D['cache'])
                $this->cacheUserInfo($UserInfo);
            Db::startTrans();
            try {
                $UserTimer->save();
                $UserLoginLog->save();
                Db::commit();
                $SendSms->delVcode();
                $this->setSuccessLogin($UserInfo);
                Cookie::delete('is_imgcode');
                return $this->ajaxReturn('登录成功', MsgCode::$success, $UserInfo);
            } catch (Exception $e) {
                Db::rollback();
                return $this->ajaxReturn('登录失败，请重试', MsgCode::$error);
            }
        } else {
            return View::fetch();
        }
    }
    public function register()
    {
        if (request()->isAjax()) {
            $D = request()->post();
            if (empty($D['is_username_type'])) {
                return $this->ajaxReturn('未知的登录方式', MsgCode::$error);
            }
            $SendSms = new SendSms;
            $SendSms->sendType = $D['is_username_type'];
            $SendSms->username = $D['username'];
            $SendSms->vcode = $D['vcode'];
            $SendSms->action = $D['type'];
            if (!$SendSms->verification()) {
                return $this->ajaxReturn($SendSms->getError(), MsgCode::$error);
            }
            $UserWxId = Session::get('UserWxId');
            if ($UserWxId) {
                $UserWxModel = UserWxModel::where(['id' => $UserWxId])->find();
                if ($UserWxModel->uid)
                    return $this->ajaxReturn('该微信已绑定用户', MsgCode::$error);
            }
            $UserQqId = Session::get('UserQqId');
            if ($UserQqId) {
                $UserQqModel = UserQqModel::where(['id' => $UserQqId])->find();
                if ($UserQqModel->uid)
                    return $this->ajaxReturn('该QQ已绑定用户', MsgCode::$error);
            }
            $where['user.mobile'] = $D['username'];
            /*验证用户状态*/
            $UserInfo = UserModel::getWebUserInfo($where);
            if ($UserInfo) {
                if (!$UserInfo['status']) {
                    return $this->ajaxReturn($UserInfo['disable_msg'], MsgCode::$error);
                }
                $UserTimer = UserTimerModel::where(['uid' => $UserInfo['id']])->find();
                $UserTimer->login_time = time();
                $UserTimer->login_ip = request()->ip();
                $UserTimer->login_devices = request()->header('user-agent');
                $UserLoginLog = new UserLoginLogModel;
                $UserLoginLog->uid = $UserInfo->id;
                $UserLoginLog->appid = request()->ApiInfo['app_id'];
                $UserLoginLog->ip = request()->ip();
                $UserLoginLog->devices_id = substr(request()->header('user-agent'), 0, 200);
                if ($UserWxId && !empty($UserInfo['wx']))
                    return $this->ajaxReturn('该用户已绑定微信', MsgCode::$error);
                if ($UserQqId && !empty($UserInfo['qq']))
                    return $this->ajaxReturn('该用户已绑定QQ', MsgCode::$error);
                if (!empty($D['cache']) && $D['cache'])
                    $this->cacheUserInfo($UserInfo);
                Db::startTrans();
                try {
                    $UserTimer->save();
                    $UserLoginLog->save();
                    if ($UserWxId) {
                        $UserWxModel->uid = $UserInfo['id'];
                        $UserWxModel->save();
                    }
                    if ($UserQqId) {
                        $UserQqModel->uid = $UserInfo['id'];
                        $UserQqModel->save();
                    }
                    Db::commit();
                    $SendSms->delVcode();
                    $this->setSuccessLogin($UserInfo);
                    Cookie::delete('is_imgcode');
                    Session::delete('BindUserInfo');
                    Session::delete('UserWxId');
                    Session::delete('UserQqId');
                    return $this->ajaxReturn('登录成功', MsgCode::$success, $UserInfo);
                } catch (Exception $e) {
                    Db::rollback();
                    return $this->ajaxReturn('登录失败，请重试', MsgCode::$error);
                }
            }
            if (empty($D['password']))
                $D['password']=Str::random(6);
            /**
             * 用户验证
             */
            try {
                validate(LoginValidate::class)->scene('register')->check($D);
            } catch (ValidateException $e) {
                return $this->ajaxReturn($e->getError(), MsgCode::$error);
            }
            $passHash = Str::random(4);
            /*用户信息*/
            $User = new UserModel;
            $User->mobile = $D['username'];
            $User->password = UserModel::getPassword($passHash, $D['password']);
            $User->password_hash = $passHash;
            /*用户详细信息*/
            $UserInfo = new UserInfoModel;
            if (Session::has('BindUserInfo')) {
                $BindUserInfo = Session::get('BindUserInfo');
                $UserInfo->nickname = $BindUserInfo['nickname'];
                $UserInfo->headimg = config('xy_default_avatar.user');
                $headimg = UploadFile::downWxAvatar($BindUserInfo['headimg']);
                if ($headimg['code'] === 0)
                    $UserInfo->headimg = $headimg['data']['path'];
            } else {
                $UserInfo->nickname = base64_encode(config('basic.nickname_header') . substr_replace($D['username'], '****', 3, 4));
                $UserInfo->headimg = config('xy_default_avatar.user');
            }
            $UserInfo->role_type = $D['role_type'] ? 1 : 0;
            $UserInfo->app_id = request()->ApiInfo['app_id'];
            /*用户时间线*/
            $UserTimer = new UserTimerModel;
            $UserTimer->online_time = time();
            $UserTimer->online_ip = request()->ip();
            $UserTimer->online_devices = substr(request()->header('user-agent'), 0, 200);
            $UserTimer->login_time = time();
            $UserTimer->login_ip = request()->ip();
            $UserTimer->login_devices = substr(request()->header('user-agent'), 0, 200);
            $UserTimer->register_time = time();
            $UserTimer->register_ip = request()->ip();
            $UserTimer->register_devices = substr(request()->header('user-agent'), 0, 200);
            $UserVipModel = new UserVipModel;
            $UserVipModel->update_vip = 0;

            $PushTaskModel = new PushTaskModel;
            $PushTaskModel->event       =   'registerSuccess';
            $PushTaskModel->data        =   json_encode(['username' => $D['username'], 'password' => $D['password']], JSON_UNESCAPED_UNICODE);

            //企业入驻提醒
            $AdminPushTaskModel=\app\common\controller\Index::EnterprisesToRemind($User);

            // 启动事务
            Db::startTrans();
            try {
                $User->save();
                $UserInfo->uid = $User->id;
                $UserTimer->uid = $User->id;
                $UserVipModel->uid = $User->id;
                $UserVipModel->save();
                $UserInfo->save();
                $UserTimer->save();

                $PushTaskModel->uid = $User->id;
                $PushTaskModel->save();
                
                if ($UserInfo->role_type==1){
                    $AdminPushTaskModel->uid = $User->id;
                    $AdminPushTaskModel->save();
                }
                if ($UserWxId) {
                    $UserWxModel->uid = $User->id;
                    $UserWxModel->save();
                }
                if ($UserQqId) {
                    $UserQqModel->uid = $User->id;
                    $UserQqModel->save();
                }
                // 提交事务
                Db::commit();
                Session::delete('BindUserInfo');
                Session::delete('UserWxId');
                Session::delete('UserQqId');
            } catch (\Exception $e) {
                // 回滚事务
                Db::rollback();
                return $this->ajaxReturn('注册失败，请重试', MsgCode::$error);
            }
            $SendSms->delVcode();
            $where['user.id'] = $User->id;
            $UserInfo = UserModel::getWebUserInfo($where);
            $this->setSuccessLogin($UserInfo);
            Cookie::delete('is_imgcode');
            return $this->ajaxReturn('注册成功', MsgCode::$success, $UserInfo);
        } else {
            return View::fetch();
        }
    }
    public function bind()
    {
        $key = request()->get('key');
        if ($key) {
            $Data = Session::get('BindUserInfo' . $key);
            if ($Data) {
                View::assign('UserInfo', $Data);
                return View::fetch();
            }
        }
        return redirect('/system/maintenance?msg=第三方信息为空，请重新授权');
    }
    public function getVcode()
    {
        if (request()->isAjax()) {
            $D = request()->post();
            $is_imgcode = intval(Cookie::get('is_imgcode'), 0);
            if (!CaptchaController::captcha_check($D))
                return $this->ajaxReturn('验证码错误', MsgCode::$error);
            $is_imgcode = $is_imgcode + 1;
            /**
             * 用户验证
             */
            try {
                validate(LoginValidate::class)->scene('getCode')->check($D);
            } catch (ValidateException $e) {
                Cookie::set('is_imgcode', $is_imgcode);
                return $this->ajaxReturn($e->getError(), MsgCode::$error);
            }
            switch ($D['is_username_type']) {
                case 'email':
                    $msg = LoginValidate::VerificationEmailSendSum($D['username']);
                    if ($msg) {
                        Cookie::set('is_imgcode', $is_imgcode);
                        return $this->ajaxReturn($msg, MsgCode::$error);
                    }
                    break;
                case 'mobile':
                    $msg = LoginValidate::VerificationMobileSendSum($D['username']);
                    if ($msg) {
                        Cookie::set('is_imgcode', $is_imgcode);
                        return $this->ajaxReturn($msg, MsgCode::$error);
                    }
                    break;
                default:
                    Cookie::set('is_imgcode', $is_imgcode);
                    return $this->ajaxReturn('未知的验证方式', MsgCode::$error);
                    break;
            }
            $SendSms = new SendSms;
            $SendSms->sendType = $D['is_username_type'];
            $SendSms->username = $D['username'];
            $SendSms->action = $D['type'];
            if ($SendSms->sendVcode()) {
                return $this->ajaxReturn('验证码已发送');
            } else {
                return $this->ajaxReturn($SendSms->getError(), MsgCode::$error);
            }
        }
    }
    public function verificationVcode()
    {
        if (request()->isAjax()) {
            $D = request()->post();
            /**
             * 用户验证
             */
            try {
                validate(LoginValidate::class)->scene('verificationVcode')->check($D);
            } catch (ValidateException $e) {
                return $this->ajaxReturn($e->getError(), MsgCode::$error);
            }
            $SendSms = new SendSms;
            $SendSms->sendType = $D['is_username_type'];
            $SendSms->username = $D['username'];
            $SendSms->vcode = $D['vcode'];
            $SendSms->action = $D['type'];
            if ($SendSms->verification()) {
                return $this->ajaxReturn();
            } else {
                return $this->ajaxReturn($SendSms->getError(), MsgCode::$error);
            }
        }
    }
    public function cacheUserInfo($UserInfo)
    {
        $key = md5(request()->ip() . '&' . $UserInfo->id . '&' . time());
        Cache::set($key, $UserInfo->toArray(), 3600 * 24 * 7);
        Cookie::set('cacheUserInfo', $key, 3600 * 24 * 7);
    }
    public function setSuccessLogin($UserInfo)
    {
        if (!Session::get('User')) {
            $key = md5('Message:&' . request()->ip() . '&' . $UserInfo->id . '&' . time() . '&' . Str::random(8));
            $UserInfo->token = $key;
            $UserInfo->client_id = [];
            Session::set('User', $UserInfo->toArray());
            Cache::set('Message::' . $key, $UserInfo->id);
        }
    }
    public function loginQrcode()
    {
        $G = request()->get();
        $logo_url = str_replace('/public/', '/', config('web.icon'));
        $logo_url = str_replace('/uploads', 'uploads', $logo_url);
        $qrObj = new QrcodeUtil([
            'logo'      =>  true,
            'logo_url'  =>  $logo_url
        ]);
        $scheme = config('web.downUrl') . '/qrlogin/' . $G['scheme'] . '/' . request()->ip();
        return response($qrObj->createServer($scheme))->header([
            'Content-Type' => $qrObj->_qr->getContentType()
        ]);
    }
    public function qrlogin($client_id, $to_client_id)
    {
        $User = Cache::pull(md5($to_client_id . $client_id));
        if ($User && $User['uid'] && $User['ip'] === request()->ip()) {
            /*验证用户状态*/
            $UserInfo = UserModel::getWebUserInfo(['user.id' => $User['uid']]);
            if (!$UserInfo)
                return $this->ajaxReturn('用户信息不存在', MsgCode::$error);
            if (!$UserInfo['status'])
                return $this->ajaxReturn($UserInfo['disable_msg'], MsgCode::$error);
            $UserTimer = UserTimerModel::where(['uid' => $UserInfo->id])->find();
            $UserTimer->login_time = time();
            $UserTimer->login_ip = request()->ip();
            $UserTimer->login_devices = 'scan_qr_login';
            $UserLoginLog = new UserLoginLogModel;
            $UserLoginLog->uid = $UserInfo->id;
            $UserLoginLog->appid = request()->ApiInfo['app_id'];
            $UserLoginLog->ip = request()->ip();
            $UserLoginLog->devices_id = 'scan_qr_login';
            Db::startTrans();
            try {
                $UserTimer->save();
                $UserLoginLog->save();
                Db::commit();
                $this->setSuccessLogin($UserInfo);
                return $this->ajaxReturn('登录成功', MsgCode::$success);
            } catch (Exception $e) {
                Db::rollback();
                return $this->ajaxReturn('登录失败，请重试', MsgCode::$error);
            }
        } else {
            return $this->ajaxReturn('授权失败，请重试', MsgCode::$error);
        }
    }
    /**
     * [captcha 手动验证码]
     * @return [type] [description]
     */
    public function captcha()
    {
        return CaptchaController::captcha();
    }
}
